/*
 * RefHandle.h
 *
 *  Created on: Sep 26, 2011
 *      Author: Walter
 */

#ifndef REFHANDLE_H_
#define REFHANDLE_H_

#include <iostream>

using namespace std;

template<typename T> class RefHandle {

private:
	T * p; // het beheerde object
	size_t * refptr; // de referentie teller
public:
	// manage reference count as well as pointer
	RefHandle() :refptr(new size_t(1)), p(0) {
		cout << "constructor" << endl;
	}

	RefHandle(T* t) :refptr(new size_t(1)), p(t) {
		cout << "constructor met binnenkoment classe" << endl;
	}

	RefHandle(const RefHandle & h) :refptr(h.refptr), p(h.p) {
		++*refptr;
		cout << "constructor met binnenkoment const ref klasse" << endl;
	}

	~RefHandle() {
		if (--*refptr == 0) { // de laatste RefHandle?
							  // ja, alles opruimen
			delete refptr;
			delete p;
		}
	}

	RefHandle & operator =(const RefHandle & rhs) {
		++*rhs.refptr;
		// free the left-hand side,
		// destroying pointers if appropriate
		if (--*refptr == 0) { // de laatste RefHandle ?
			delete refptr;
			delete p;
		}
		// copy the values from the right-hand side
		refptr = rhs.refptr;
		p = rhs.p;
		return *this;
	}

	operator bool() const {
		return p;
	}

	T & operator *() const {
		return *p;
	}
	;
	T* operator ->() const {
		return p;
	}
	;

	void makeUnique() {
		if (*refptr != 1) {
			--*refptr;
			refptr = new size_t(1);
			p = p ? clone(p) : 0;
		}
	}

	T * clone(const T * tp) {
		return tp->clone();
	}

};

#endif /* REFHANDLE_H_ */
